package com.chiyou.common.utils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import redis.clients.jedis.Jedis;



/**
 * redis工具类实现hashSet功能
 * key:attr-val,attr-val...
 * @author 陈嘉瑛
 * @version 2015-11-18
 *
 */
public class RedisUtilHset extends RedisBase{
	private static Log logger = LogFactory.getLog(RedisUtilHset.class);

	/**
	 * 通过哈希设置一组属性值到redis中
	 * 一次只能设置一组：attr-attrVal
	 * 作者：陈嘉瑛
	 * 时间：2015-11-18
	 * @param key
	 * @param attrName
	 * @param attrVal
	 */
	public Boolean hset(Object key, Object attrName, Object attrVal){
		return hset(SerializeUtil.serialize(key), 
				SerializeUtil.serialize(attrName), SerializeUtil.serialize(attrVal));
	}

	/**
	 * 把序列化好的键值对保存到redis中
	 * 一次只能设置一组：attr-attrVal
	 * 作者：陈嘉瑛
	 * 时间：2015-11-18
	 * @param key
	 * @param attrName
	 * @param attrVal
	 * @return
	 */
	public Boolean hset(byte[] key, byte[] attrName, byte[] attrVal){
		Jedis jedis = super.getJedis();
		try{
			Long num = jedis.hset(key, attrName, attrVal);
			if(num != null && num > 0) return true;
		}catch(Exception e){
			logger.debug(e.getMessage());
		}finally{
			super.returnPool(jedis);
		}
		return false;
	}

	/**
	 * 一次保存多个attr-attrVal到redis中对应的key
	 * 作者：陈嘉瑛
	 * 时间：2015-11-18
	 * @param key
	 * @param attrName
	 * @param attrVal
	 * @return
	 */
	public Boolean hmset(Object key, Object[] attrName, Object[] attrVal){
		Map<byte[], byte[]> attr = new HashMap<byte[], byte[]>();
		for(int i=0; i<attrName.length; i++){
			attr.put(SerializeUtil.serialize(attrName[i]), SerializeUtil.serialize(attrVal[i]));
		}
		return hmset(SerializeUtil.serialize(key), attr);
	}

	/**
	 * 保存已经序列化好的多组attr-attrVal到redis中对应的key
	 * 作者：陈嘉瑛
	 * 时间：2015-11-18
	 * @param key
	 * @param attr
	 * @return
	 */
	public Boolean hmset(byte key[], Map<byte[], byte[]> attr){
		Jedis jedis = super.getJedis();
		try{
			String rs = jedis.hmset(key, attr);
			if("ok".equalsIgnoreCase(rs)) return true;
		}catch(Exception e){
			logger.debug(e.getMessage());
		}finally{
			super.returnPool(jedis);
		}
		return false;
	}

	/**
	 * 获取一组指定key的属性名及属性值
	 * 作者：陈嘉瑛
	 * 时间：2015-11-18
	 * @param key
	 * @param arrtName
	 * @return
	 */
	public Object hget(Object key, Object arrtName){
		return hget(SerializeUtil.serialize(key), SerializeUtil.serialize(arrtName));
	}

	/**
	 * 获取一组指定key的属性名及属性值
	 * key和attrName 需要序列化
	 * 作者：陈嘉瑛
	 * 时间：2015-11-18
	 * @param key
	 * @param attrName
	 * @return
	 */
	public Object hget(byte[] key, byte[] attrName){
		Jedis jedis = super.getJedis();
		try{
			Object obj = SerializeUtil.unserialize(jedis.hget(key, attrName));
			return obj;
		}catch(Exception e){
			logger.debug(e.getMessage());
		}finally{
			super.returnPool(jedis);
		}
		return new Object();
	}

	/**
	 * 一次获取多组attr-attrVal通过制定的key
	 * 作者：陈嘉瑛
	 * 时间：2015-11-18
	 * @param key
	 * @param attrs
	 * @return
	 */
	public List<Object> hmget(Object key, Object...attrs){
		byte[][] ls = new byte[attrs.length][];
		for(int i=0; i<attrs.length; i++){
			ls[i] = SerializeUtil.serialize(attrs[i]);
		}
		return hmget(SerializeUtil.serialize(key),ls);
	}

	/**
	 * 一次获取多组attr-attrVal通过制定的key
	 * key和attrs属性名需要序列化
	 * 作者：陈嘉瑛
	 * 时间：2015-11-18
	 * @param key
	 * @param attrs
	 * @return
	 */
	public List<Object> hmget(byte[] key, byte[]...attrs){
		Jedis jedis = super.getJedis();
		try{
			List<byte[]> ls = jedis.hmget(key, attrs);
			List<Object> lsObj = new ArrayList<Object>();
			for(byte[] b : ls){
				lsObj.add(SerializeUtil.unserialize(b));
			}
			return lsObj;
		}catch(Exception e){
			logger.debug(e.getMessage());
		}finally{
			super.returnPool(jedis);
		}
		return new ArrayList<Object>();
	}

	/**
	 * 一次获取key下的所有attr
	 * 作者：陈嘉瑛
	 * 时间：2015-11-18
	 * @param key
	 */
	public Map<Object, Object> hgetAll(Object key){
		return hgetAll(SerializeUtil.serialize(key));
	}

	/**
	 * 一次获取key下的所有attr
	 * key需要序列化
	 * 作者：陈嘉瑛
	 * 时间：2015-11-18
	 * @param key
	 */
	public Map<Object, Object> hgetAll(byte[] key) {
		Jedis jedis = super.getJedis();
		try{
			Map<byte[], byte[]> map = jedis.hgetAll(key);
			Map<Object, Object> rsMap = new HashMap<Object, Object>();
			for(byte[] attrName : map.keySet()){
				rsMap.put(SerializeUtil.unserialize(attrName), SerializeUtil.unserialize(map.get(attrName)));
			}
			return rsMap;
		}catch(Exception e){
			logger.debug(e.getMessage());
		}finally{
			super.returnPool(jedis);
		}
		return new HashMap<Object, Object>();
	}

	/**
	 * 判断key中是否存在对应的attrName属性名
	 * 作者：陈嘉瑛
	 * 时间：2015-11-18
	 * @param key
	 * @param attrName
	 * @return
	 */
	public Boolean hexists(Object key, Object attrName){
		return hexists(SerializeUtil.serialize(key), SerializeUtil.serialize(attrName));
	}

	/**
	 * 判断key中是否存在对应的attrName属性名
	 * key和attrName需要序列化
	 * 作者：陈嘉瑛
	 * 时间：2015-11-18
	 * @param key
	 * @param attrName
	 * @return
	 */
	public Boolean hexists(byte[] key, byte[] attrName) {
		Jedis jedis = super.getJedis();
		try{
			Boolean rs = jedis.hexists(key, attrName);
			return rs;
		}catch(Exception e){
			logger.debug(e.getMessage());
		}finally{
			super.returnPool(jedis);
		}
		return false;
	}

	/**
	 * 获取指定key的所有属性名，attrName
	 * 作者：陈嘉瑛
	 * 时间：2015-11-18
	 * @param key
	 * @return
	 */
	public List<Object> hkeys(Object key){
		return hkeys(SerializeUtil.serialize(key));
	}

	/**
	 * 获取指定key的所有属性名，attrName
	 * key需要序列化
	 * 作者：陈嘉瑛
	 * 时间：2015-11-18
	 * @param key
	 * @return
	 */
	public List<Object> hkeys(byte[] key){
		Jedis jedis = super.getJedis();
		try{
			Set<byte[]> rs = jedis.hkeys(key);
			List<Object> rsObj = new ArrayList<Object>();
			for(byte[] b :rs){
				rsObj.add(SerializeUtil.unserialize(b));
			}
			return rsObj;
		}catch(Exception e){
			logger.debug(e.getMessage());
		}finally{
			super.returnPool(jedis);
		}
		return new ArrayList<Object>();
	}

	/**
	 * 删除指定key下的指定属性
	 * 作者：陈嘉瑛
	 * 时间：2015-11-18
	 * @param key
	 * @param attr
	 * @return
	 */
	public Boolean hdel(Object key, Object attr){
		return hdel(SerializeUtil.serialize(key), SerializeUtil.serialize(attr));
	}

	/**
	 * 删除指定key下的指定属性
	 * key 和 attr 需要序列化
	 * 作者：陈嘉瑛
	 * 时间：2015-11-18
	 * @param key
	 * @param attr
	 * @return
	 */
	public Boolean hdel(byte[] key, byte[] attr) {
		Jedis jedis = super.getJedis();
		try{
			Long num = jedis.hdel(key, attr);
			if(num != null && num > 0) return true;
		}catch(Exception e){
			logger.debug(e.getMessage());
		}finally{
			super.returnPool(jedis);
		}
		return false;
	}
	
	/**
	 * 
	 * 功能描述：重写redis指定key下的指定属性
	 * @author Anna
	 * @createDate 2015-11-23
	 * @param key
	 * @param attrName
	 * @param attrVal
	 * @return
	 * <p>
	 * 修改历史 ：(修改人，修改时间，修改原因/内容)
	 * </p>
	 */
	public Boolean rhset(Object key, Object attrName, Object attrVal){
		if(this.hexists(key, attrName)){
			this.hdel(key, attrName);
		}
		return this.hset(key, attrName, attrVal);
	}

}
